home *** CD-ROM | disk | FTP | other *** search
- //
- // Event.m
- // Copyright (c) 1988, 1989, 1990 by Jiro Nakamura
- // All rights reserved
- //
- // Implementation definition of class Event. Event handles
- // the database management of Cassandra.
- //
- // RCS Information
- // Revision Number-> $Revision: 2.10 $
- // Last Revised-> $Date: 91/01/27 15:35:26 $
- //
- static char rcsid[] = "$Id: Event.m,v 2.10 91/01/27 15:35:26 jiro Exp Locker: jiro $";
-
- #import "Event.h"
- #import <objc/objc.h>
- #import <strings.h>
- #import <appkit/Panel.h> /* for NXRunAlertPanel */
- #import "cass.h"
- #import "calendar.h"
- #import "Global.h"
- #import "misc.h"
- #import <sys/types.h>
- #import <sys/stat.h>
-
- // Defining DEBUG for Event can sometimes get very screen messy
- // since Cassandra uses it so often
- // #undef DEBUG
-
- int fgeti( int *i , FILE *fp)
- {
- char buffer[10];
- if( fgets(buffer, 10, fp) == NULL)
- return -1;
- *i = atoi(buffer);
- return 0;
- }
-
-
- @implementation Event
-
- + newAt:(const char*) eFile
- {
- self = [super new];
- strcpy(eventFile,eFile);
-
- priority = 50;
- destroy = snoozeNo = snoozeInt =0;
- anniversary = annvSpecial = 0;
- present = next = previous = 0;
- showMessage = TRUE;
- playAlarm = TRUE;
-
- strcpy(alarmSound, ALARMSOUND);
- strcpy(msg,"empty");
- return self;
- }
-
- + new
- {
- fprintf(stderr,"This should never be called!");
- self = [super new];
- return self;
- }
-
- - free
- {
- #ifdef DEBUG
- fprintf(stderr,"Event.m:Free ->Closing event!\n");
- #endif
- [super free];
- return nil;
- }
-
- //
- //
- // Messages that affect how the file is stored on disk
- //
- //
-
- - default: sender
- {
- present = 0;
- previous = next = -1;
- destroy = 1;
- anniversary = annvSpecial = snoozeInt = snoozeNo = priority = 0;
- ts.tm_sec = ts.tm_min = ts.tm_hour = 0;
- ts.tm_mday = ts.tm_mon = ts.tm_year = 0;
- ts.tm_wday = ts.tm_yday = ts.tm_isdst = 0;
-
- strcpy(msg, "");
- strcpy(alarmSound,[global alarmSound]);
- return self;
- }
-
-
- - readEvent: (EFileLink) here /* read itself from the event file */
- {
- FILE * source;
- static char errormsg[128], buffer[10];
- char *tp; // temporary pointer
- struct stat statBuf;
-
- #ifdef DEBUG
- fprintf(stderr, "------------------------\n"
- "[Event readEvent: %d]\n",here);
- #endif
-
- if( here < 0)
- {
- NXRunAlertPanel("File Seek Error",
- "Cannot seek to a negative number.",
- "OK",NULL,NULL);
- strcpy(msg, "Illegal event/link value....");
- return nil;
- }
-
- /* Let's first check to make sure we aren't reading an empty file */
- stat( eventFile, &statBuf);
- if( statBuf.st_size < 100) // It can not be this short
- {
- strcpy(msg, CASSANDRAVERSION);
- next = previous = 0;
- present = here;
- [self writeEvent: here];
- fprintf(stderr, "%s: Event list not initialized. "
- "Initializing....\n",
- PROGNAME);
- return nil;
- }
-
- sprintf(errormsg, "Error occured while trying to read event file %s",
- eventFile);
- source = fileOpen(eventFile, "r+",errormsg);
-
- sprintf(errormsg, "An fatal error occured when we were trying "
- "to seek to event number %d for reading event "
- "file %s.\n This program has crashed.",
- here, eventFile);
- if( fileSeek(source, here, errormsg) == NULL)
- {
- next = previous = -1;
- present = here;
- return nil;
- }
-
- present = fgetnum(source);
- if( present != here)
- {
- fprintf(stderr,
- "%s: Uh oh.... File header gives %d instead of %d.\n"
- "%s: We've most probably run out off the end of %s.\n"
- "%s: Not to worry. :-) I'll extend it.\n",
- PROGNAME ,present, here,
- PROGNAME, [global eventFile],
- PROGNAME);
- next = previous = -1;
- present = here;
- fclose(source);
- return nil;
- }
- else
- {
- previous = fgetnum(source);
- next = fgetnum(source);
- }
-
- fgets( buffer, 10, source);
- fgets( buffer, 10, source);
-
- fgeti( &priority, source);
- fgeti( &destroy, source);
- fgeti( &anniversary, source);
- fgeti( &snoozeNo, source);
- fgeti( &snoozeInt, source);
-
- fgets( buffer, 10, source);
- fgets( buffer, 10, source);
-
- fgeti( &ts.tm_sec, source);
- fgeti( &ts.tm_min, source);
- fgeti( &ts.tm_hour, source);
- fgeti( &ts.tm_mday, source);
- fgeti( &ts.tm_mon, source);
- fgeti( &ts.tm_year, source);
- fgeti( &ts.tm_wday, source);
- fgeti( &ts.tm_yday, source);
- fgeti( &ts.tm_isdst, source);
-
- fgets( alarmSound, 100, source); // We gotta strip the final
- tp = rindex( alarmSound, '\n'); // newline and replace it with
- if( tp != NULL) // a NULL character.
- *tp = '\0';
-
- fgets( buffer, 10, source);
- fgets( buffer, 10, source);
- fgets( buffer, 10, source);
- fgets( buffer, 10, source);
-
- fgets(msg,MESSAGE_SIZE,source);
-
- ts.tm_wday = wday(ts.tm_mday, ts.tm_mon+1, 1900+ts.tm_year);
- ts.tm_yday = yday(ts.tm_mday, ts.tm_mon+1, ts.tm_year+1900);
-
- playAlarm = TRUE;
- deleteSound = FALSE;
- annvSpecial = 0;
-
- if( alarmSound[0] == '-')
- {
- char buf[255];
-
- strcpy(buf, alarmSound);
- strcpy(alarmSound, buf+1);
- playAlarm = FALSE;
- }
- else
- {
- if( alarmSound[0] == '?')
- {
- char buf[255];
- strcpy(buf, alarmSound);
- strcpy(alarmSound, buf+1);
- deleteSound = TRUE;
- }
- }
-
- if( msg[0] == ';')
- {
- char buf[MESSAGE_SIZE];
-
- strcpy(buf, msg);
- strcpy(msg, buf+1);
- showMessage = FALSE;
- }
- else
- showMessage = TRUE;
-
- fclose(source);
- return self;
- }
-
- - firstEvent
- {
- #ifdef DEBUG
- fprintf(stderr,"Reading in the first event.\n");
- #endif
-
- [self readEvent : 0];
- if( [self next] == 0)
- return self;
- [self readEvent : [self next]];
- return self;
- }
-
- - writeEvent: (EFileLink) here
- /* write itself into the event file using present as its index */
- {
- FILE *source;
- char errormsg[256], bufAlarm[256], bufMessage[256];
-
- if( here < 0)
- {
- NXRunAlertPanel( "Write Error",
- "We can't write to a negative event number.",
- "OK",NULL,NULL);
- return nil;
- }
-
- #ifdef DEBUG
- fprintf(stderr, "------------------------\n"
- "[Event writeEvent: %d]: Opening event with "
- "<%s>!\n",here, eventFile);
- #endif
-
- sprintf(errormsg, "Fatal error when trying to write to event file %s",
- eventFile);
- source = fileOpen(eventFile, "r+",errormsg);
-
- sprintf(errormsg, "%s: An fatal error occured when we were trying to "
- "seek to event number %d for writing in event file %s.\n"
- " This program has crashed.", PROGNAME, here, eventFile);
- fileSeek(source, here, errormsg);
-
- present = here;
-
- if( ts.tm_year > 1900)
- ts.tm_year -= 1900;
-
- if( playAlarm == FALSE)
- {
- strcpy(bufAlarm, "-");
- strcat(bufAlarm,alarmSound);
- }
- else
- {
- if( deleteSound == TRUE )
- {
- strcpy(bufAlarm, "?");
- strcat(bufAlarm,alarmSound);
- }
- else
- strcpy(bufAlarm, alarmSound);
- }
-
- if( showMessage == FALSE)
- {
- strcpy(bufMessage, ";");
- strcat(bufMessage, msg);
- }
- else
- strcpy(bufMessage, msg);
-
-
- if(fprintf( source, "%d\n%d\n%d\n"
- "\n\n"
- "%d\n%d\n%d\n"
- "%d\n%d\n"
- "\n\n"
- "%d\n%d\n%d\n"
- "%d\n%d\n%d\n"
- "%d\n%d\n%d\n"
- "%s\n\n"
- "\n\n\n"
- "%s\n",
- present, previous, next,
- priority,destroy, anniversary,
- snoozeNo, snoozeInt,
- ts.tm_sec, ts.tm_min, ts.tm_hour,
- ts.tm_mday, ts.tm_mon, ts.tm_year,
- ts.tm_wday, ts.tm_yday, ts.tm_isdst,
- bufAlarm, bufMessage) == -1)
- {
- fprintf(stderr, "%s: Event.m: Error occured writing file.",
- PROGNAME);
- strcpy(msg, "Error occured in writing out Elink number.\n\n");
- fclose(source);
- return nil;
- }
-
- #ifdef DEBUG
- fprintf(stderr, "%s: Wrote out Efilelink.\n Here = %d, "
- "Previous = %d, Next=%d\n", PROGNAME,
- here, previous, next);
- fprintf(stderr, "%s: Date: time = %d:%d, day= %d, "
- "month = %d, year = %d.\n\n",PROGNAME,
- ts.tm_hour, ts.tm_min, ts.tm_mday, ts.tm_mon,
- ts.tm_year);
- fprintf(stderr,"%s: AlarmSound =%s\n", PROGNAME, bufAlarm);
- #endif
-
- fclose(source);
- return self;
- }
-
- - (EFileLink) insertEvent
- {
- return [self insertEventFrom : 1];
- }
-
-
-
- /* insert itself into the file with current day as index */
- /* and starting from <here> in searching for a open deleted space */
- - (EFileLink) insertEventFrom : (EFileLink) here
- {
- id event, step;
- int loop;
-
-
- // First things first, we must check the format of our time structure
- // since we have given other functions full freedom to scew it up
-
- fixTmStructure( &ts);
-
- event = [Event newAt:eventFile];
- step = [Event newAt:eventFile];
- [event readEvent:0];
- for( [event readEvent: [event next]];
- [event present] != 0 && timeCompare([event time], &ts) < 1;
- [event readEvent:[event next]])
- {
- #ifdef DEBUG
- fprintf(stderr, "From %d looping onto %d\n",[event present],[event next]);
- #endif
- }
- #ifdef DEBUG
- fprintf(stderr, "inserting between %d <- event -> %d.\n",[event previous], [event present]);
- #endif
-
- previous = [event previous];
- next = [event present];
-
- [step setNext: 0];
- for( loop = here; !([step next] == -1 && [step previous] == -1); [step readEvent: loop++])
- {
- #ifdef DEBUG
- fprintf(stderr, "reading at %d.\n",loop);
- #endif
- }
-
- present = [step present];
-
- [self writeEvent: present];
-
- [step readEvent: previous];
- [step setNext : present];
- [step writeEvent:previous];
-
- [step readEvent: next];
- [step setPrevious : present];
- [step writeEvent:next];
-
- [step free];
- [event free];
- #ifdef DEBUG
- fprintf(stderr,"successfully inserted %d <- %d -> %d\n\n",[self previous],[self present], [self next]);
- #endif
-
-
- return( [self present] );
- }
-
- /* delete itself from the file with present as index */
- - deleteEvent : (EFileLink) here
- {
- id previousEvent, nextEvent;
-
- #ifdef DEBUG
- fprintf(stderr, "Deleting <%d>\n\n",here);
- #endif
-
- if( here <= 0)
- {
- NXRunAlertPanel(NULL,"You cannot delete link 0 or below. OK?",
- "Shucks...",NULL,NULL);
- fprintf(stderr,"Can't delete the header. Here = %d.\n\n",
- here);
- return nil;
- }
-
- previousEvent= [Event newAt: eventFile];
- nextEvent = [Event newAt:eventFile];
-
- [previousEvent readEvent :here];
- if( ( [previousEvent previous] == -1 ) ||
- ( [previousEvent next] == -1 ) )
- {
- /* link was already deleted, so we can't delete it..... */
- strcpy(msg, "Can't delete link because it's already been "
- "deleted!?!\n\n");
- return nil;
- }
-
- /* Set the previous_link of the next link */
- /* to the one of the previous one */
- [nextEvent readEvent :[previousEvent next]];
- [nextEvent setPrevious : [previousEvent previous]];
- [nextEvent writeEvent :[previousEvent next]];
-
- /* do the same confusing spiel for previous */
- [nextEvent readEvent :[previousEvent previous] ];
- [nextEvent setNext : [previousEvent next]];
- [nextEvent writeEvent :[previousEvent previous] ];
-
- /* cancel out the header to finally kill it */
- /* and write it out */
- [previousEvent setNext : -1];
- [previousEvent setPrevious :-1];
- [previousEvent writeEvent :here];
-
- #ifdef DEBUG
- fprintf(stderr, "Record %d successfully deleted.\n\n",
- here);
- #endif
-
- [previousEvent free];
- [nextEvent free];
- return self;
- }
-
- /* delete if it is not an anniversary event, update otherwise */
- - (int) murderEvent : (EFileLink) here
- {
- Event *event;
-
- #ifdef DEBUG
- fprintf(stderr,"Arrggh! Help! I'm getting murdered! "
- "(says Event <%d>)\n\n",
- here);
- #endif
-
- event = [Event newAt :eventFile];
- [event readEvent : here]; // Read the event in
- [event deleteEvent : here]; // Delete the event
-
- if( (int) ([event anniversary]/100) == 0) // No anniversary
- return -1;
-
- [event setTime: fixAnniversary( [event time], [event anniversary],
- [event annvSpecial])];
- // Fix the next event time and reinsert it
-
- // Use the same EFilelink space that we deleted, this saves
- // us time and maybe some confusion
- return( [event insertEventFrom:here] );
- }
-
-
- - (EFileLink) present
- {
- return present;
- }
-
- - (EFileLink) previous
- {
- return previous;
- }
-
- - (EFileLink) next
- {
- return next;
- }
-
- - setPresent : (EFileLink) apresent
- {
- present = apresent;
- return self;
- }
- - setPrevious : (EFileLink) aprevious
- {
- previous =aprevious;
- return self;
- }
-
- - setNext : (EFileLink) anext
- {
- next = anext;
- return self;
- }
-
- - (struct tm *) time
- {
- return &ts;
- }
-
- - setTime : (struct tm *) time
- {
- ts = *time;
- return self;
- }
-
- - setMday : (int) x
- {
- ts.tm_mday = x;
- return self;
- }
-
- - (int) mday;
- {
- return( ts.tm_mday);
- }
-
- - setMon: (int) x
- {
- ts.tm_mon = x;
- return self;
- }
-
- - (int) mon
- {
- return (ts.tm_mon);
- }
-
- - setYear: (int) x
- {
- ts.tm_year = x;
- return self;
- }
-
- - (int) year
- {
- return (ts.tm_year);
- }
-
- - setHour: (int) x
- {
- ts.tm_hour = x;
- return self;
- }
-
- - (int) hour
- {
- return (ts.tm_hour);
- }
-
- - setMin: (int) x
- {
- ts.tm_min = x;
- return self;
- }
-
- - (int) min
- {
- return(ts.tm_min);
- }
-
- - setSec: (int) x
- {
- ts.tm_sec = x;
- return self;
- }
-
- - (int) sec
- {
- return(ts.tm_sec);
- }
-
- - (int) destroy
- {
- return destroy;
- }
-
- - setDestroy : (int) dst
- {
- destroy = dst;
- return self;
- }
-
-
- - (int) anniversary
- {
- return anniversary;
- }
-
- - setAnniversary : (int) anv
- {
- anniversary = anv;
- return self;
- }
-
-
- - (int) annvSpecial
- {
- return annvSpecial;
- }
-
- - setAnnvSpecial : (int) anvS
- {
- annvSpecial = anvS;
- return self;
- }
-
- - (int) snoozeNo
- {
- return snoozeNo;
- }
-
- - setSnoozeNo : (int) sn
- {
- snoozeNo = sn;
- return self;
- }
-
-
- - (int) snoozeInt
- {
- return snoozeInt;
- }
-
- - setSnoozeInt : (int) si
- {
- snoozeInt = si;
- return self;
- }
-
- - (int) priority
- {
- return priority;
- }
-
- - setPriority : (int) si
- {
- priority = si;
- return self;
- }
-
- - (char *) alarmSound
- {
- return alarmSound;
- }
-
- - setAlarmSound : (char *) aS
- {
- strcpy( alarmSound, aS);
- return self;
- }
-
- - setPlayAlarm: (BOOL) aFlag
- {
- playAlarm = aFlag;
- return self;
- }
-
-
- - (BOOL) playAlarm
- {
- return playAlarm;
- }
-
- - setShowMessage: (BOOL) aFlag
- {
- showMessage = aFlag;
- return self;
- }
-
-
- - (BOOL) showMessage
- {
- return showMessage;
- }
-
-
- - (char *) message
- {
- return msg;
- }
-
-
- - (BOOL) deleteSound
- {
- return deleteSound;
- }
-
- - setDeleteSound: (BOOL) aFlag
- {
- deleteSound = aFlag;
- return self;
- }
-
- - setMessage : (char *) message
- {
- strcpy( msg, message);
- return self;
- }
-
- - setWday : (int) wd
- {
- ts.tm_wday = wd;
- return self;
- }
-
- - setYday : (int) yd
- {
- ts.tm_yday = yd;
- return self;
- }
-
- - (int) wday
- {
- return ts.tm_wday;
- }
-
- - (int) yday
- {
- return ts.tm_yday;
- }
- @end
-
-
- struct tm *fixAnniversary( struct tm *time, int mode, int sub)
- {
- #ifdef DEBUG
- fprintf(stderr,"Fixing weekly special: %s, %d, %d\n", ascMyTime(time, YES, NO),
- mode, sub);
- #endif
-
- switch( (int) mode / 100)
- {
- /* Don't worry about overflows as we add intervals to */
- /* our dates, insertEvent is smart enough to handle it */
- case 0:
- return time; /* No anniversary */
- case 1: /* If it is a day anniversary */
- time->tm_mday+= (mode - 100);
- break;
- case 2: /* Weekly anniversary */
- time -> tm_mday += ((mode - 200) * 7 );
- break;
- case 3: /* Monthly anniversary */
- time-> tm_mon += (mode - 300);
- break;
- case 4: /* Yearly anniversary */
- time -> tm_year += (mode - 400);
- break;
- case 5: /* Special weekly */
- default:
- fprintf(stderr,
- "%s: I do not recognize anniversary event: %d.\n",
- PROGNAME,
- mode);
- return time;
- }
-
- fixTmStructure( time);
- return time;
- }
-
-
-